#include "./WizInnerThread.hpp"
#include "../../Include/System/WizTimer.hpp"

#if (WIZ_CFG_PLATFORM == WIZ_CFG_PLATFORM_WINDOWS)
#include "./Windows/Thread/WizInnerWindowsThread.hpp"
#elif (WIZ_CFG_PLATFORM == WIZ_CFG_PLATFORM_LINUX)
#endif /*WIZ_CFG_PLATFORM*/

namespace Wiz
{
    namespace Thread
    {
        ////////////////////////////////////////////////////////////////////////
        namespace Runnable
        {
            namespace Extend
            {
                Type::Type()
                {
                    m_Suspend = ::Wiz::AtomicCount::Create();
                }
                ::Wiz::Void::Type Type::Run()
                {
                    WIZ_ASSERT(::Wiz::IsValidPtr(m_Suspend));

                    if (this->Enter())
                    {
                        while (this->Exit() == ::Wiz::Bool::False)
                        {
                            if (m_Suspend->Count() == 0)
                            {
                                this->Running();
                            }
                            else
                            {
                                ::Wiz::Timer::Sleep(1);
                            }
                        }
                    }
                }
                ::Wiz::Void::Type Type::Suspend()
                {
                    m_Suspend->Increment();
                }
                ::Wiz::Void::Type Type::Unsuspend()
                {
                    m_Suspend->Decrement();
                }
            } /// end of namespace Extend
        } /// end of namespace Runnable
        ////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////
        ::Wiz::Bool::Type Type::CreateCore(::Wiz::Thread::Runnable::Ptr RPtr, ::Wiz::Bool::In AutoRM)
        {
            WIZ_ASSERT(::Wiz::IsValidPtr(RPtr));
            ::Wiz::Inner::Thread::Ptr TPtr;
#           if (WIZ_CFG_PLATFORM == WIZ_CFG_PLATFORM_WINDOWS)
            TPtr = new ::Wiz::Inner::Thread::Windows::Type(RPtr);
#           elif (WIZ_CFG_PLATFORM == WIZ_CFG_PLATFORM_LINUX)
            TPtr = new ::Wiz::Inner::Thread::Linux::Type(RPtr);
#           endif /*WIZ_CFG_PLATFORM*/

            if (::Wiz::NotValidPtr(TPtr))
            {
                return ::Wiz::Bool::False;
            }

            RPtr->m_AutoRM = AutoRM;
            this->m_Core = TPtr;
            RPtr->m_TLSDataNodePtr = WIZ_NULLPTR;

            return TPtr->Start();
        }

        ::Wiz::Void::Type Type::DestroyCore()
        {
            ::Wiz::SafeDelete(this->m_Core);
        }
        ////////////////////////////////////////////////////////////////////////
    } /// end of namespace Thread
} /// end of namespace Wiz

